package com.smart.common.scheduler.service;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import com.google.common.collect.Lists;
import com.smart.common.domain.BaseEntity;
import com.smart.common.enums.ConstructionStatusEnum;
import com.smart.common.enums.ProjectTempTaskStatusEnum;
import com.smart.common.enums.ReportTypeEnum;
import com.smart.common.utils.AssertUtil;
import com.smart.mapper.ProjectTempTaskMapper;
import com.smart.model.convert.ProjectTempTaskConvert;
import com.smart.model.domain.ProjectReportDO;
import com.smart.model.domain.ProjectTempTaskDO;
import com.smart.model.dtomapper.ProjectTempTaskDtoMapper;
import com.smart.model.vo.ProjectTempTaskVO;
import com.smart.model.vo.ProjectVO;
import com.smart.service.ProjectReportService;
import com.smart.service.ProjectService;
import com.smart.service.ProjectTempTaskService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

/**
 * @author macbook
 */
@Slf4j
@Component
public class TempTaskScheduleService {

    @Autowired
    private ProjectTempTaskService projectTempTaskService;
    @Autowired
    private ProjectTempTaskMapper projectTempTaskMapper;
    @Autowired
    private ProjectService projectService;
    @Autowired
    private ProjectReportService projectReportService;

    /**
     * 生成临时提报任务
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean createTempTask() {
        //扫描所有到期但是未开始的临时提报任务
        List<ProjectTempTaskVO> taskList = projectTempTaskService.listAlreadyStartByStatus(ProjectTempTaskStatusEnum.UN_START);
        if (CollectionUtils.isEmpty(taskList)) {
            log.info("目标临时提报任务为空...");
            return true;
        }
        //扫描所有"在施"或者"完工待验"的项目
        List<ProjectVO> projects = projectService.listProjectByStatus(Lists.newArrayList(ConstructionStatusEnum.RUNNING.getCode(), ConstructionStatusEnum.WAIT_ACCEPT.getCode()));
        if (CollectionUtils.isEmpty(projects)) {
            log.info("不存在-在施/完工待验的项目...");
            return true;
        }
        //为对应的项目生成临时提报任务单
        List<ProjectReportDO> entityList = buildDOList(taskList, projects);
        for (ProjectReportDO item : entityList) {
            boolean exists = projectReportService.lambdaQuery().eq(ProjectReportDO::getProjectId, item.getProjectId()).eq(ProjectReportDO::getTaskId, item.getTaskId()).exists();
            if (!exists) {
                projectReportService.save(item);
            }
        }
        //将临时提报任务标记为进行中
        for (ProjectTempTaskVO taskVO : taskList) {
            //projectTempTaskService.lambdaUpdate()
            //        .set(ProjectTempTaskDO::getStatus, ProjectTempTaskStatusEnum.RUNNING.name())
            //        .eq(BaseEntity::getId, taskVO.getId());
            projectTempTaskMapper.updateStatus(taskVO.getId(), ProjectTempTaskStatusEnum.RUNNING.name());
        }
        return true;
    }

    /**
     * 构造临时提报任务消息
     * @param taskList
     * @param projects
     * @return
     */
    private List<ProjectReportDO> buildDOList(List<ProjectTempTaskVO> taskList, List<ProjectVO> projects) {
        List<ProjectReportDO> list = Lists.newArrayList();
        for (ProjectTempTaskVO tempTaskVO : taskList) {
            for (ProjectVO project : projects) {
                ProjectReportDO reportDO = new ProjectReportDO();
                reportDO.setProjectId(project.getId());
                reportDO.setTaskId(tempTaskVO.getId());
                reportDO.setItemType(ReportTypeEnum.TEMP.name());
                list.add(reportDO);
            }
        }
        return list;
    }

    /**
     * 结束临时提报任务
     */
    public void finishTempTask() {
        //扫描所有进行中的临时提报任务
        List<ProjectTempTaskDO> projectTempTaskDOS = projectTempTaskMapper.listAlreadyStartByStatus(ProjectTempTaskStatusEnum.RUNNING.name());
        //将已经到期的提报任务标记为结束
        for (ProjectTempTaskDO item : projectTempTaskDOS) {
            Date endTime = DateUtil.endOfDay(item.getEndTime()).offset(DateField.SECOND, -1).toJdkDate();
            if (endTime.getTime() < (new Date()).getTime()) {
                item.setStatus(ProjectTempTaskStatusEnum.FINISH.name());
                projectTempTaskMapper.updateDO(item);
            }
        }

        //兼容处理，将已经过期的UN_START也置为标记为结束
        projectTempTaskMapper.updateExpiredUnStartTask();
    }

    /**
     *
     * @param taskId
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean sendTemplateTask(long taskId) {
        ProjectTempTaskDO taskDO = projectTempTaskService.getById(taskId);
        AssertUtil.assertNotNull(taskDO, "任务不存在");

        taskDO.setStartTime(new Date());
        taskDO.setStatus(ProjectTempTaskStatusEnum.RUNNING.name());
        projectTempTaskService.saveOrUpdate(taskDO);

        //为对应的项目生成临时提报任务单
        //扫描所有"在施"或者"完工待验"的项目
        List<ProjectVO> projects = projectService.listProjectByStatus(Lists.newArrayList(ConstructionStatusEnum.RUNNING.getCode(), ConstructionStatusEnum.WAIT_ACCEPT.getCode()));
        if (CollectionUtils.isEmpty(projects)) {
            log.info("不存在-在施/完工待验的项目...");
            return true;
        }

        //为对应的项目生成临时提报任务单
        List<ProjectReportDO> entityList = buildDOList(Lists.newArrayList(ProjectTempTaskDtoMapper.INSTANCE.do2VO(taskDO)), projects);
        for (ProjectReportDO reportDO : entityList) {
            boolean exists = projectReportService.lambdaQuery().eq(ProjectReportDO::getProjectId, reportDO.getProjectId()).eq(ProjectReportDO::getTaskId, reportDO.getTaskId()).exists();
            if (!exists) {
                projectReportService.save(reportDO);
            }
        }
        return true;
    }
}
